// Learn TypeScript:
//  - https://docs.cocos.com/creator/manual/en/scripting/typescript.html
// Learn Attribute:
//  - https://docs.cocos.com/creator/manual/en/scripting/reference/attributes.html
// Learn life-cycle callbacks:
//  - https://docs.cocos.com/creator/manual/en/scripting/life-cycle-callbacks.html

import SeptkapaModule from "./SeptkapaModule";
import LogModule from "./LogModule";
import DeviceModule from "./DeviceModule";
import TimeModule from "./TimeModule";

const {ccclass, property} = cc._decorator;

var formatJson = function (json, options) {    
    var reg = null,
            formatted = '',
            pad = 0,
            PADDING = '    ';
    options = options || {};
    options.newlineAfterColonIfBeforeBraceOrBracket = (options.newlineAfterColonIfBeforeBraceOrBracket === true) ? true : false;
    options.spaceAfterColon = (options.spaceAfterColon === false) ? false : true;
    reg = /([\{\}])/g;
    json = json.replace(reg, '\r\n$1\r\n');
    reg = /([\[\]])/g;
    json = json.replace(reg, '\r\n$1\r\n');
    reg = /(\,)/g;
    json = json.replace(reg, '$1\r\n');
    reg = /(\r\n\r\n)/g;
    json = json.replace(reg, '\r\n');
    reg = /\r\n\,/g;
    json = json.replace(reg, ',');
    if (!options.newlineAfterColonIfBeforeBraceOrBracket) {
        reg = /\:\r\n\{/g;
        json = json.replace(reg, ':{');
        reg = /\:\r\n\[/g;
        json = json.replace(reg, ':[');
    }
    if (options.spaceAfterColon) {
        reg = /\:/g;
        json = json.replace(reg, ':');
    }
    (json.split('\r\n')).forEach(function (node, index) {
        var i = 0,
            indent = 0,
            padding = '';

        if (node.match(/\{$/) || node.match(/\[$/)) {
            indent = 1;
        } else if (node.match(/\}/) || node.match(/\]/)) {
            if (pad !== 0) {
                pad -= 1;
            }
        } else {
                indent = 0;
        }

        for (i = 0; i < pad; i++) {
            padding += PADDING;
        }

        formatted += padding + node + '\r\n';
        pad += indent;
    });
    return formatted;
};


@ccclass
export default class FileModule {

    public static formatJson = formatJson;
    public static RootDataPath = '';

    static init () {
        this.RootDataPath = SeptkapaModule.getInstance().rootPath;
        const toolPath = this.RootDataPath;
        var initDirs = ['daily/','income/','stock/','ths/','daily/ths/','stock/daily/', 'stock/holders/', 'daily/limit'];
        for (let index = 0; index < initDirs.length; index++) {
            const dir = initDirs[index];
            if (jsb.fileUtils.isDirectoryExist(toolPath + dir) == false) {
                jsb.fileUtils.createDirectory(toolPath + dir);
            }
        }        
    }

    static checkOrMakeDir (dir: string) { 
        this.RootDataPath = SeptkapaModule.getInstance().rootPath;
        const toolPath = this.RootDataPath + dir;
        if (jsb.fileUtils.isDirectoryExist(toolPath) == false) {
            jsb.fileUtils.createDirectory(toolPath);
        }
    }

    static isFileExist (filePath: string): boolean {
        this.RootDataPath = SeptkapaModule.getInstance().rootPath;
        const toolPath = this.RootDataPath;
        filePath = toolPath + filePath;
        return jsb.fileUtils.isFileExist(filePath);
    }

    static async loadJsonAsync (jsonName: string) {
        const toolPath = this.RootDataPath;
        let filePath = toolPath + jsonName + '.json';
        if (jsb.fileUtils.isFileExist(filePath) == false) {
            return null;
        }

        var json = await new Promise((resolve) => {
            cc.assetManager.loadRemote(filePath, cc.JsonAsset, (result: Error, asset: cc.JsonAsset) => {
                if (asset && asset.json) {
                    resolve(asset.json);
                    cc.assetManager.releaseAsset(asset);
                }
            });
        });
        
        return json;
    }

    static loadString (filePath: string) {
        const toolPath = this.RootDataPath;
        filePath = toolPath + filePath;
        LogModule.log('正在加载: ' + filePath);
        if (jsb.fileUtils.isFileExist(filePath) == false) {
            return null;
        }

        let str = jsb.fileUtils.getStringFromFile(filePath);
        return str;
    }

    static loadUint8Array (filePath: string) : Uint8Array {
        const toolPath = this.RootDataPath;
        filePath = toolPath + filePath;
        LogModule.log('正在加载: ' + filePath);
        if (jsb.fileUtils.isFileExist(filePath) == false) {
            return null;
        }

        var buffer = jsb.fileUtils.getDataFromFile(filePath);
        return buffer;
    }
    
    static saveUint8Array (filePath: string, buffer: Uint8Array) : boolean {
        const toolPath = this.RootDataPath;
        filePath = toolPath + filePath;
        LogModule.log('正在保存: ' + filePath);
        if (jsb.fileUtils.isFileExist(filePath) == true) {
            jsb.fileUtils.removeFile(filePath);
        }

        return jsb.fileUtils.writeDataToFile(buffer, filePath);
    }

    static releaseJson (jsonName: string) {
        const toolPath = this.RootDataPath;
        let filePath = toolPath + jsonName + '.json';
        if (jsb.fileUtils.isFileExist(filePath)) {
            cc.assetManager.releaseAll();
        }
    }

    static isExistJson (jsonName: string) {
        const toolPath = this.RootDataPath;
        let filePath = toolPath + jsonName + '.json';
        return jsb.fileUtils.isFileExist(filePath);
    }

    static saveJson (jsonName: string, data: any) {
        const toolPath = this.RootDataPath;
        let str = JSON.stringify(data);
        str = formatJson(str, null);
        let filePath = toolPath + jsonName + '.json';
        LogModule.log('保存json: ' + filePath);
        jsb.fileUtils.writeStringToFile(str, filePath);
    }

    static saveJsonNoFormat (jsonName: string, data: any) {
        const toolPath = this.RootDataPath;
        let str = JSON.stringify(data);
        let filePath = toolPath + jsonName + '.json';
        LogModule.log('保存json: ' + filePath);
        jsb.fileUtils.writeStringToFile(str, filePath);
    }

    static async saveJsonAsync (jsonName: string, data: any, delayMs: number) {
        delayMs = 1;
        const toolPath = this.RootDataPath;
        let str = JSON.stringify(data);
        str = formatJson(str, null);
        let filePath = toolPath + jsonName + '.json';
        LogModule.log('保存json: ' + filePath);
        await new Promise((resolve) => {
            jsb.fileUtils.writeStringToFile(str, filePath);
            setTimeout(() => {
                resolve(null);
            }, delayMs);
        });
    }

    static async saveStringAsync (name: string, strData: string, delayMs: number) {
        delayMs = 1;
        if (strData == '') {
            LogModule.log('[FileModule][saveStringAsync] 保存的数据为空, name:' + name);
            strData = '没有找到数据';
        }
        const toolPath = this.RootDataPath;
        let str = strData;
        let filePath = toolPath + name + '.txt';
        
        await new Promise((resolve) => {
            jsb.fileUtils.writeStringToFile(str, filePath);
            setTimeout(() => {
                resolve(null);
            }, delayMs);
        });
        LogModule.log('已保存txt:' + filePath);
        DeviceModule.copyTextToClipboard(strData);
    }

    static async saveCsvAsync (name: string, strData: string, delayMs: number) {
        if (strData == '') {
            strData = '没有找到数据';
        }
        const toolPath = this.RootDataPath;
        let str = strData;
        let filePath = toolPath + name + '.csv';
        LogModule.log('正在保存csv:' + filePath);
        await new Promise((resolve) => {
            jsb.fileUtils.writeStringToFile(str, filePath);
            setTimeout(() => {
                resolve(null);
            }, delayMs);
        });
    }

    //   let item = {date: date, industry: industryData, conceptData: conceptData};
    static saveThsCsv (jsonName: string, data: any) {
        const toolPath = this.RootDataPath;
        //生成csv标头
        let front = '';
        let strList = [];
        for (let j = 0; j < data.length; j++) {
            const item = data[j];
            let industry = item.industry;
            front += `${item.date},,`;
            if (j == data.length - 1) {
                front += '\n';
            }
            for (let index = 0; index < industry.length; index++) {
                const dataItem = industry[index];
                if (strList[index] == null) {
                    strList[index] = '';
                }
                strList[index] += `${dataItem.name},${dataItem.change}%,`;
                if (j == data.length - 1) {
                    strList[index] += '\n';
                }
            }
        }

        for (let index = 0; index < strList.length; index++) {
            front += strList[index];
        }

        let file = toolPath + jsonName + '_industry.csv';
        jsb.fileUtils.writeStringToFile(front, file);

        front = '';
        strList = [];
        for (let j = 0; j < data.length; j++) {
            const item = data[j];
            let concept = item.concept;
            front += `${item.date},,`;
            if (j == data.length - 1) {
                front += '\n';
            }
            for (let index = 0; index < concept.length; index++) {
                const dataItem = concept[index];
                if (strList[index] == null) {
                    strList[index] = '';
                }
                strList[index] += `${dataItem.name},${dataItem.change}%,`;
                if (j == data.length - 1) {
                    strList[index] += '\n';
                }
            }
        }

        for (let index = 0; index < strList.length; index++) {
            front += strList[index];
        }

        file = toolPath + jsonName + '_concept.csv';
        jsb.fileUtils.writeStringToFile(front, file);
    }

    static deleteToday () {
        let dir = this.RootDataPath + 'daily/ths/';
        jsb.fileUtils.removeDirectory(dir);
        let file = this.RootDataPath + 'ths_plate_member.json';
        jsb.fileUtils.removeFile(file);
        let today = TimeModule.getInstance().curTradeDate();
        file = this.RootDataPath + `stock/daily/daily_all_${today}.json`;
        jsb.fileUtils.removeFile(file);
    }

    static deleteMonth () {
        let dir = this.RootDataPath + '/stock/holders/';
        jsb.fileUtils.removeDirectory(dir);
        let file = this.RootDataPath + 'stock_list.json';
        jsb.fileUtils.removeFile(file);
    }
    
}
